/**
 * @author Ahammer
 * @date 2009 06
 * @knownissue 2011 01: MinFilterDescriptor.MIN_MASK_SQUARE_SEPARABLE does not work properly at the image borders
 */

/*
 * This file is part of Iqm.
 * Copyright (c) 2010-2011 Helmut Ahammer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package op;


import java.awt.RenderingHints;
import java.awt.image.renderable.ParameterBlock;
import javax.media.jai.BorderExtender;
import javax.media.jai.JAI;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.operator.MaxFilterDescriptor;
import javax.media.jai.operator.MaxFilterShape;
import javax.media.jai.operator.MedianFilterDescriptor;
import javax.media.jai.operator.MedianFilterShape;
import javax.media.jai.operator.MinFilterDescriptor;
import javax.media.jai.operator.MinFilterShape;


/**
 * This is the main image processing class
 * There exist two approaches:
 * A user defined JAI operator is just called 
 * or:
 * The actual processing is implemented in this class 
 */
public class IqmRankOperator{ 


  public IqmRankOperator() {
	  //WARNING: Don't declare fields here
	  //Fields declared here aren't thread safe!   
  }
  /**
   * 
   * @param ParametrBlockJAI pb
   */
  public Object run(ParameterBlockJAI pbJAI){
	  Object ob = null;
      //ob = JAI.create("IqmRank".toLowerCase(), pbJAI, null);     
      
	  PlanarImage pi = (PlanarImage) pbJAI.getSource(0);
	  int method      = pbJAI.getIntParameter("Method");
	  int kernelShape = pbJAI.getIntParameter("KernelShape");
	  int maskSize    = pbJAI.getIntParameter("KernelSize");

	  if (method == 0){ //Median
		  MedianFilterShape maskShape = null;
		  if (kernelShape == 0) maskShape = MedianFilterDescriptor.MEDIAN_MASK_SQUARE;
		  if (kernelShape == 1) maskShape = MedianFilterDescriptor.MEDIAN_MASK_PLUS;  
		  if (kernelShape == 2) maskShape = MedianFilterDescriptor.MEDIAN_MASK_X;  
		  if (kernelShape == 3) maskShape = MedianFilterDescriptor.MEDIAN_MASK_SQUARE_SEPARABLE;
		  	   
		  RenderingHints rh = new RenderingHints(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY));
		  ParameterBlock pb = new ParameterBlock();
	      pb.addSource(pi);
		  pb.add(maskShape);
		  pb.add(maskSize);
		  ob = JAI.create("MedianFilter", pb, rh);
	  }
	  if (method == 1){ //Min
		  MinFilterShape maskShape = null;
		  if (kernelShape == 0) maskShape = MinFilterDescriptor.MIN_MASK_SQUARE;
		  if (kernelShape == 1) maskShape = MinFilterDescriptor.MIN_MASK_PLUS;  
		  if (kernelShape == 2) maskShape = MinFilterDescriptor.MIN_MASK_X;  
		  if (kernelShape == 3) maskShape = MinFilterDescriptor.MIN_MASK_SQUARE_SEPARABLE;
		  	  	 
		  RenderingHints rh = new RenderingHints(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY));
		  ParameterBlock pb = new ParameterBlock();
	      pb.addSource(pi);
		  pb.add(maskShape);
		  pb.add(maskSize);
		  ob = JAI.create("MinFilter", pb, rh);
	  }
	  if (method == 2){ //Max
		  MaxFilterShape maskShape = null;
		  if (kernelShape == 0) maskShape = MaxFilterDescriptor.MAX_MASK_SQUARE;
		  if (kernelShape == 1) maskShape = MaxFilterDescriptor.MAX_MASK_PLUS;  
		  if (kernelShape == 2) maskShape = MaxFilterDescriptor.MAX_MASK_X;  
		  if (kernelShape == 3) maskShape = MaxFilterDescriptor.MAX_MASK_SQUARE_SEPARABLE;
		  	  	 
		  RenderingHints rh = new RenderingHints(JAI.KEY_BORDER_EXTENDER, BorderExtender.createInstance(BorderExtender.BORDER_COPY));
		  ParameterBlock pb = new ParameterBlock();
	      pb.addSource(pi);
		  pb.add(maskShape);
		  pb.add(maskSize);
		  ob = JAI.create("MaxFilter", pb, rh);
	  }
			
	  return ob;
  }
}
